import { HttpError, ValidationError } from '../utils/errors.js';
import logger from '../utils/logger.js';

export default function errorHandler() {
  return async (ctx, next) => {
    try {
      await next();

      // 处理404
      if (ctx.status === 404 && !ctx.body) {
        ctx.throw(404, 'Resource not found');
      }
    } catch (err) {
      // 初始化错误对象
      let error = err;

      // 错误标准化处理
      if (!(error instanceof HttpError)) {
        switch (error.name) {
          // 处理JWT错误
          case 'JsonWebTokenError':
          case 'TokenExpiredError':
            error = new HttpError(401, 'Invalid authentication token');
            break;

          // 处理Mongoose验证错误
          case 'ValidationError':
            error = new ValidationError(error.errors);
            break;

          // 处理文件上传错误
          case 'MulterError':
            error = new HttpError(413, error.message);
            break;

          // 处理数据库操作错误
          case 'CastError':
            error = new HttpError(400, 'Invalid resource identifier');
            break;

          // 处理默认系统错误
          default:
            error = new HttpError(
              error.statusCode || 500,
              error.message || 'Internal server error'
            );
        }
      }

      if (error.statusCode >= 500) {
        logger.error({  // 使用对象形式传递参数
          msg: 'Server Error',
          code: error.statusCode,
          message: error.message,
          stack: error.stack,
          originalError: err
        });
      } else {
        logger.warn({  // 显式声明msg字段
          msg: 'Client Error',
          code: error.statusCode,
          message: error.message,
          path: ctx.path,
          params: ctx.params,
          query: ctx.query
        });
      }

      // 构造标准化响应
      ctx.status = error.statusCode;
      ctx.body = {
        code: error.statusCode,
        message: error.expose ? error.message : 'Internal Server Error',
        ...(error.details && { errors: error.details }),
        ...(process.env.NODE_ENV === 'development' && {
          stack: error.stack,
          originalError: err.message
        })
      };

      // 确保头信息正确
      ctx.set('Content-Type', 'application/problem+json');
    }
  };
}